/*
 * ArtistPanel.java
 *
 * Created on June 11, 2005, 12:30 PM
 */
package com.bff.slimserver.musicjukebox.ui;

import java.util.*;
import javax.swing.tree.*;
import com.bff.bjj.ui.component.BJJPanel;
import com.bff.slimserver.musicjukebox.lib.actions.PlaylistAddFolderAction;
import com.bff.slimserver.musicjukebox.lib.actions.PlaylistInsertFolderAction;
import com.bff.slimserver.musicjukebox.lib.actions.PlaylistLoadFolderAction;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTree;
import org.bff.slimserver.SlimFolderBrowser;
import org.bff.slimserver.SlimPlaylist;
import org.bff.slimserver.exception.SlimException;
import org.bff.slimserver.exception.SlimResponseException;
import org.bff.slimserver.musicobjects.SlimFolderObject;

/**
 *
 * @author  Bill
 */
public class FolderTreePanel
        extends BJJPanel
        implements ExplorerIface {

    private DefaultMutableTreeNode topFolderNode = new DefaultMutableTreeNode("Music Folder");
    private DefaultTreeModel treeFolderModel = new DefaultTreeModel(topFolderNode);
    private SlimFolderBrowser folderBrowser;
    private SlimPlaylist playlist;
    private Action addFolderAction;
    private Action loadFolderAction;
    private Action insertFolderAction;

    public FolderTreePanel() {
    }

    /** Creates new form ArtistPanel */
    public FolderTreePanel(SlimFolderBrowser folderBrowser, SlimPlaylist playlist) {
        this.folderBrowser = folderBrowser;
        this.playlist = playlist;


        createActions();
        initComponents();

        createNodes();

        folderTree.expandPath(new TreePath(topFolderNode));

        loadProgressBar.setVisible(false);
    }

    private void createNodes() {
        createFolderNodes(topFolderNode);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel3 = new javax.swing.JPanel();
        treeScrollPane = new javax.swing.JScrollPane();
        folderTree = new javax.swing.JTree(treeFolderModel);
        folderTree.setCellRenderer(new FolderTreeCellRenderer());
        loadProgressBar = new javax.swing.JProgressBar();
        btnPanel = new com.bff.bjj.ui.component.BJJPanel();
        btnAddItem = new javax.swing.JButton();
        btnInsertItem = new javax.swing.JButton();
        btnLoadItem = new javax.swing.JButton();

        setLayout(new java.awt.BorderLayout());

        jPanel3.setLayout(new java.awt.BorderLayout());

        treeScrollPane.setPreferredSize(new java.awt.Dimension(200, 322));

        folderTree.setRowHeight(30);
        folderTree.addTreeWillExpandListener(new javax.swing.event.TreeWillExpandListener() {
            public void treeWillCollapse(javax.swing.event.TreeExpansionEvent evt)throws javax.swing.tree.ExpandVetoException {
            }
            public void treeWillExpand(javax.swing.event.TreeExpansionEvent evt)throws javax.swing.tree.ExpandVetoException {
                treeWillExpanded(evt);
            }
        });
        folderTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                folderTreeValueChanged(evt);
            }
        });
        treeScrollPane.setViewportView(folderTree);

        jPanel3.add(treeScrollPane, java.awt.BorderLayout.CENTER);

        loadProgressBar.setIndeterminate(true);
        loadProgressBar.setString("Loading Folder");
        jPanel3.add(loadProgressBar, java.awt.BorderLayout.SOUTH);

        add(jPanel3, java.awt.BorderLayout.CENTER);

        btnAddItem.setAction(addFolderAction);
        btnPanel.add(btnAddItem);

        btnInsertItem.setAction(insertFolderAction);
        btnPanel.add(btnInsertItem);

        btnLoadItem.setAction(loadFolderAction);
        btnPanel.add(btnLoadItem);

        add(btnPanel, java.awt.BorderLayout.SOUTH);
    }// </editor-fold>//GEN-END:initComponents

    private void treeWillExpanded(javax.swing.event.TreeExpansionEvent evt) {//GEN-FIRST:event_treeWillExpanded

        TreePath selectedPath = evt.getPath();
        folderTree.setEnabled(false);
        loadProgressBar.setVisible(true);
        try {

            Object selObject =
                    ((DefaultMutableTreeNode) selectedPath.getLastPathComponent()).getUserObject();

            DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedPath.getLastPathComponent();

            if (!node.isRoot()) {
                node.removeAllChildren();
                if (selObject instanceof SlimFolderObject) {
                    fillFolder((DefaultMutableTreeNode) selectedPath.getLastPathComponent(), (SlimFolderObject) selObject);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            folderTree.setEnabled(true);
            loadProgressBar.setVisible(false);
        }
    }//GEN-LAST:event_treeWillExpanded

    private void folderTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_folderTreeValueChanged
        if (!getSelectedFolders().isEmpty()) {
            enableActions();
            getAddFolderAction().setFolders(getSelectedFolders());
            getLoadFolderAction().setFolders(getSelectedFolders());
            getInsertFolderAction().setFolders(getSelectedFolders());
        } else {
            disableActions();
        }
    }//GEN-LAST:event_folderTreeValueChanged
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAddItem;
    private javax.swing.JButton btnInsertItem;
    private javax.swing.JButton btnLoadItem;
    private javax.swing.JPanel btnPanel;
    private javax.swing.JTree folderTree;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JProgressBar loadProgressBar;
    private javax.swing.JScrollPane treeScrollPane;
    // End of variables declaration//GEN-END:variables

    private Collection<SlimFolderObject> getSelectedFolders() {
        TreePath[] path = folderTree.getSelectionPaths();
        List<SlimFolderObject> list = new ArrayList<SlimFolderObject>();

        for (int i = 0; i < path.length; i++) {
            TreePath treePath = path[i];
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent();
            if (node == null) //Nothing is selected.
            {
                return null;
            }

            Object nodeInfo = node.getUserObject();

            if (nodeInfo instanceof SlimFolderObject) {
                list.add((SlimFolderObject) nodeInfo);
            }
        }


        return list;
    }

    private void createFolderNodes(DefaultMutableTreeNode top) {

        DefaultMutableTreeNode folderNode = null;
        List<SlimFolderObject> folderList = null;

        loadProgressBar.setVisible(true);

        try {
            folderList = new ArrayList<SlimFolderObject>(getFolderBrowser().getFolders());
            //java.util.Collections.sort(artistList);
            top.removeAllChildren();

            for (SlimFolderObject f : folderList) {
                folderNode = new DefaultMutableTreeNode(f);
                folderNode.add(new DefaultMutableTreeNode());
                top.add(folderNode);
            }


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            loadProgressBar.setVisible(false);
        }
    }

    public void refreshComponents() {
        createFolderNodes(topFolderNode);
    }

    public SlimPlaylist getPlaylist() {
        return playlist;
    }

    public void setPlaylist(SlimPlaylist playlist) {
        this.playlist = playlist;
    }

    /**
     * @return the folderBrowser
     */
    public SlimFolderBrowser getFolderBrowser() {
        return folderBrowser;
    }

    /**
     * @param folderBrowser the folderBrowser to set
     */
    public void setFolderBrowser(SlimFolderBrowser folderBrowser) {
        this.folderBrowser = folderBrowser;
    }

    private void fillFolder(DefaultMutableTreeNode defaultMutableTreeNode, SlimFolderObject slimFolderObject) {
        try {
            List<SlimFolderObject> objects = new ArrayList<SlimFolderObject>(getFolderBrowser().getFolderElements(slimFolderObject));

            for (SlimFolderObject object : objects) {
                DefaultMutableTreeNode node = new DefaultMutableTreeNode(object);
                defaultMutableTreeNode.add(node);
                if (object.getObjectType().equals(SlimFolderObject.OBJECTTYPE.FOLDER)) {
                    node.add(new DefaultMutableTreeNode());
                }
            }
        } catch (SlimResponseException ex) {
            Logger.getLogger(FolderTreePanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void createActions() {
        addFolderAction = new PlaylistAddFolderAction(playlist, null);
        loadFolderAction = new PlaylistLoadFolderAction(playlist, null);
        insertFolderAction = new PlaylistInsertFolderAction(playlist, null);
        disableActions();
    }

    private PlaylistAddFolderAction getAddFolderAction() {
        return (PlaylistAddFolderAction) addFolderAction;
    }

    private PlaylistLoadFolderAction getLoadFolderAction() {
        return (PlaylistLoadFolderAction) loadFolderAction;
    }

    private PlaylistInsertFolderAction getInsertFolderAction() {
        return (PlaylistInsertFolderAction) insertFolderAction;
    }

    private void enableActions() {
        addFolderAction.setEnabled(true);
        loadFolderAction.setEnabled(true);
        insertFolderAction.setEnabled(true);
    }

    private void disableActions() {
        addFolderAction.setEnabled(false);
        loadFolderAction.setEnabled(false);
        insertFolderAction.setEnabled(false);
    }

    private class ExplorerSelectPanel extends JPanel {

        private Image image;

        public ExplorerSelectPanel() {
            try {
                image = ImageIO.read(ExplorerButton.class.getResourceAsStream("/resources/slimserver/explorer_button_panel_background.png"));
            } catch (IOException ex) {
                Logger.getLogger(ExplorerListPanel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }
    }

    private class ExplorerButton extends JButton {

        private Image image;
        private Image unSelectedimage;
        private Image selectedImage;

        public ExplorerButton() {
            try {
                unSelectedimage = ImageIO.read(ExplorerButton.class.getResourceAsStream("/resources/slimserver/explorer_button_background.png"));
                selectedImage = ImageIO.read(ExplorerButton.class.getResourceAsStream("/resources/slimserver/explorer_button_selected_background.png"));
            } catch (IOException ex) {
                Logger.getLogger(ExplorerListPanel.class.getName()).log(Level.SEVERE, null, ex);
            }
            setContentAreaFilled(false);
            setUnselectedBackground();
            setBorder(BorderFactory.createEtchedBorder(Color.GRAY, Color.GRAY));
        }

        @Override
        public void paintComponent(Graphics g) {
            g.drawImage(image, 0, 0, this);
            super.paintComponent(g);
        }

        public void setSelectedBackground() {
            image = selectedImage;
            repaint();
        }

        public void setUnselectedBackground() {
            image = unSelectedimage;
            repaint();
        }
    }

    private class FolderTreeCellRenderer extends DefaultTreeCellRenderer {

        private Icon iconAudio = new ImageIcon(getClass().getResource("/resources/slimserver/musicnote_small.png"));

        @Override
        public Component getTreeCellRendererComponent(JTree tree,
                Object value,
                boolean selected,
                boolean expanded,
                boolean leaf,
                int row,
                boolean hasFocus) {

            super.getTreeCellRendererComponent(
                    tree,
                    value,
                    selected,
                    expanded,
                    leaf,
                    row,
                    hasFocus);

            if (((DefaultMutableTreeNode) value).getUserObject() instanceof SlimFolderObject) {
                SlimFolderObject folder = (SlimFolderObject) ((DefaultMutableTreeNode) value).getUserObject();
                if (folder.getObjectType().equals(SlimFolderObject.OBJECTTYPE.TRACK)
                        || folder.getObjectType().equals(SlimFolderObject.OBJECTTYPE.PLAYLIST)) {
                    setIcon(iconAudio);
                }

                setText(folder.getFileName());
            }

            return this;
        }
    }
}
